package com.healthyeating.manage.service.impl;

import java.util.*;
import java.util.stream.Collectors;

import com.healthyeating.common.core.domain.entity.SysDictData;
import com.healthyeating.common.utils.DateUtils;
import com.healthyeating.common.utils.SecurityUtils;
import com.healthyeating.manage.domain.AssocNutrition;
import com.healthyeating.manage.domain.Drink;
import com.healthyeating.manage.mapper.AssocNutritionMapper;
import com.healthyeating.system.service.ISysDictTypeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.healthyeating.manage.mapper.DrinkMapper;
import com.healthyeating.manage.service.IDrinkService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 饮水记录Service业务层处理
 *
 * @author 段奇乐
 * @date 2024-12-20
 */
@Service
public class DrinkServiceImpl implements IDrinkService {

    @Autowired
    private DrinkMapper drinkMapper;

    @Autowired
    private AssocNutritionMapper assocNutritionMapper;

    @Autowired
    private ISysDictTypeService sysDictTypeService;

    /**
     * 将waterType从数字转换为对应的dictLabel
     */
    private String getWaterDictLabel(Integer waterType) {
        List<SysDictData> waterTypeList = sysDictTypeService.selectDictDataByType("water_type");
        if (waterTypeList != null) {
            for (SysDictData water : waterTypeList) {
                if (water.getDictValue().equals(waterType.toString())) {
                    return water.getDictLabel();
                }
            }
        }
        return null;
    }

    /**
     * 查询饮水记录
     *
     * @param waterId 饮水记录主键
     * @return 饮水记录
     */
    @Override
    public Drink selectDrinkByWaterId(Long waterId) {
        return drinkMapper.selectDrinkByWaterId(waterId);
    }

    /**
     * 查询饮水记录列表
     *
     * @param drink 饮水记录
     * @return 饮水记录
     */
    @Override
    public List<Drink> selectDrinkList(Drink drink) {
        if (drink.getCreateTime() != null) {
            Map<String, Object> map = DateUtils.extractTime(drink.getCreateTime());
            drink.setStartOfDay((Date) map.get("startOfDay"));
            drink.setEndOfDay((Date) map.get("endOfDay"));
        }
        drink.setUserId(SecurityUtils.getUserId());
        return drinkMapper.selectDrinkList(drink);
    }

    /**
     * 批量新增饮水记录
     *
     * @param drinkList 饮水记录
     * @return 结果
     */
    @Override
    @Transactional
    public int insertDrink(List<Drink> drinkList) {
        List<Drink> insterList = drinkList.stream().peek(drink -> {
            drink.setCreateTime(DateUtils.getNowDate());
            drink.setUserId(SecurityUtils.getUserId());
        }).collect(Collectors.toList());
        List<AssocNutrition> assocNutritionList = new ArrayList<>();
        insterList.forEach(drink -> {
            AssocNutrition assocNutrition = new AssocNutrition();
            assocNutrition.setAssocId(drink.getWaterId());
            assocNutrition.setSource("tb_drink");
            assocNutrition.setDietName(getWaterDictLabel(drink.getWaterType()));
            assocNutrition.setCreateTime(DateUtils.getNowDate());
            assocNutrition.setUpdateTime(DateUtils.getNowDate());
            assocNutrition.setUpdateBy(SecurityUtils.getUsername());
            assocNutritionList.add(assocNutrition);
        });
        List<AssocNutrition> _assocNutritionList = assocNutritionMapper.selectAssocNutritionList(new AssocNutrition());
        // 查询是否已经存在，如果存在，将重复的部分移除
//        assocNutritionList.removeIf(assocNutrition -> _assocNutritionList.stream().anyMatch(_assocNutrition -> _assocNutrition.getDietName().equals(assocNutrition.getDietName())));
//        assocNutritionMapper.batchInsertAssocNutrition(assocNutritionList);
        List<AssocNutrition> newAssocNutritionList = assocNutritionList.stream()
                .filter(assocNutrition -> _assocNutritionList.stream()
                        .noneMatch(_assocNutrition -> _assocNutrition.getDietName().equals(assocNutrition.getDietName()))
                )
                .collect(Collectors.toList());
        // 5. 如果有新数据，则执行批量插入
        if (!newAssocNutritionList.isEmpty()) {
            assocNutritionMapper.batchInsertAssocNutrition(newAssocNutritionList);
        }
        return drinkMapper.batchInsertDrinks(insterList);
    }

    /**
     * 修改饮水记录
     *
     * @param drinkList 饮水记录
     * @return 结果
     */
    @Override
    @Transactional
    public int updateDrink(List<Drink> drinkList) {
        // 筛选出没有drinkId的数据
        List<Drink> insertDrinkList = drinkList.stream().filter(drink -> drink.getWaterId() == null).collect(Collectors.toList());
        // 筛选出有drinkId的数据
        List<Drink> updateDrinkList = drinkList.stream().filter(drink -> drink.getWaterId() != null).collect(Collectors.toList());
        // 查询当天所有的饮水记录
        Drink drink = new Drink();
        drink.setCreateTime(DateUtils.getNowDate());
        Map<String, Object> map = DateUtils.extractTime(drink.getCreateTime());
        drink.setUserId(SecurityUtils.getUserId());
        drink.setStartOfDay((Date) map.get("startOfDay"));
        drink.setEndOfDay((Date) map.get("endOfDay"));
        List<Drink> drinks = drinkMapper.selectDrinkList(drink);
        // 比较updateDrinkList和drinks的大小，如果updateDrinkList比drinks小，删除掉drinks中多的一部分
        if (updateDrinkList.size() < drinks.size()) {
            List<Long> drinkIds = drinks.stream().map(Drink::getWaterId).collect(Collectors.toList());
            List<Long> updateDrinkIds = updateDrinkList.stream().map(Drink::getWaterId).collect(Collectors.toList());
            List<Long> deleteDrinkIds = drinkIds.stream().filter(drinkId -> !updateDrinkIds.contains(drinkId)).collect(Collectors.toList());
            drinkMapper.deleteDrinkByWaterIds(deleteDrinkIds.toArray(new Long[0]));
        }
        // 批量新增
        if (!insertDrinkList.isEmpty()) {
            List<Drink> insertDrinks = insertDrinkList.stream().peek(drinkItem -> {
                drinkItem.setCreateTime(DateUtils.getNowDate());
                drinkItem.setUserId(SecurityUtils.getUserId());
            }).collect(Collectors.toList());
            drinkMapper.batchInsertDrinks(insertDrinks);
            List<AssocNutrition> assocNutritionList = new ArrayList<>();
            insertDrinks.forEach(_drink -> {
                AssocNutrition assocNutrition = new AssocNutrition();
                assocNutrition.setAssocId(_drink.getWaterId());
                assocNutrition.setSource("tb_drink");
                assocNutrition.setDietName(getWaterDictLabel(_drink.getWaterType()));
                assocNutrition.setCreateTime(DateUtils.getNowDate());
                assocNutrition.setUpdateTime(DateUtils.getNowDate());
                assocNutrition.setUpdateBy(SecurityUtils.getUsername());
                assocNutritionList.add(assocNutrition);
            });
            List<AssocNutrition> _assocNutritionList = assocNutritionMapper.selectAssocNutritionList(new AssocNutrition());
            // 查询是否已经存在，如果存在，将重复的部分移除
//            assocNutritionList.removeIf(assocNutrition -> _assocNutritionList.stream().anyMatch(_assocNutrition -> _assocNutrition.getDietName().equals(assocNutrition.getDietName())));
//            assocNutritionMapper.batchInsertAssocNutrition(assocNutritionList);
            List<AssocNutrition> newAssocNutritionList = assocNutritionList.stream()
                    .filter(assocNutrition -> _assocNutritionList.stream()
                            .noneMatch(_assocNutrition -> _assocNutrition.getDietName().equals(assocNutrition.getDietName())))
                    .collect(Collectors.toList());
            if (!newAssocNutritionList.isEmpty()) {
                assocNutritionMapper.batchInsertAssocNutrition(newAssocNutritionList);
            }
        }
        return drinkMapper.batchUpdateDrink(updateDrinkList);
    }

    /**
     * 批量删除饮水记录
     *
     * @param waterIds 需要删除的饮水记录主键
     * @return 结果
     */
    @Override
    public int deleteDrinkByWaterIds(Long[] waterIds) {
        return drinkMapper.deleteDrinkByWaterIds(waterIds);
    }

    /**
     * 删除饮水记录信息
     *
     * @param waterId 饮水记录主键
     * @return 结果
     */
    @Override
    public int deleteDrinkByWaterId(Long waterId) {
        return drinkMapper.deleteDrinkByWaterId(waterId);
    }
}
